const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs-extra');
const axios = require('axios');
const TiandituService = require('../services/tiandituService');
const MBTilesService = require('../services/mbtilesService');
const { getTilesInBoundingBox } = require('../utils/mapUtils');

// 预定义的1x1透明PNG图片Buffer（Base64转Buffer）
// 这是一个1x1像素的透明PNG图片的Base64编码
const TRANSPARENT_PNG_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
const TRANSPARENT_PNG_BUFFER = Buffer.from(TRANSPARENT_PNG_BASE64, 'base64');

// 配置路径
const offlineMapDir = path.join(__dirname, '../../offline-maps');
const mbtilesDir = path.join(__dirname, '../../mbtiles');

// 使用全局MBTiles服务实例和配置
let mbtilesService = global.mbtilesService || null;
let enableMbtiles = process.env.USE_MBTILES === 'true';

// 如果全局服务存在但未初始化，则初始化它
if (enableMbtiles && mbtilesService) {
    mbtilesService.init(mbtilesDir).catch(error => {
        console.error('MBTiles服务初始化失败:', error);
        enableMbtiles = false;
    });
}

// 全局变量，用于跟踪离线地图样式是否已更新
let isOfflineMapStyleUpdated = false;
let offlineMapStyle = null;

// 根据文件格式获取内容类型
function getContentType(format) {
  const contentTypeMap = {
    'png': 'image/png',
    'jpg': 'image/jpeg',
    'jpeg': 'image/jpeg',
    'webp': 'image/webp',
    'svg': 'image/svg+xml',
    'pbf': 'application/x-protobuf'
  };
  return contentTypeMap[format.toLowerCase()] || null;
}

// 获取地图配置信息
router.get('/config', (req, res) => {
  console.log('===== 地图配置请求 (mapRoutes) =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求方法:', req.method);
  console.log('请求参数:', req.query);
  
  // 修改字段名以匹配客户端期望的格式
  const config = {
    apiKey: process.env.TIANDITU_API_KEY,
    center: [116.397428, 39.90923], // 北京市中心坐标
    zoom: 10
  };
  res.json(config);
});

// 获取当前地图模式
router.get('/get-mode', (req, res) => {
  console.log('===== 获取地图模式请求 =====');
  const currentMode = req.app.locals.mapMode || 'offline';
  console.log('当前模式:', currentMode);
  res.json({ mode: currentMode });
});

// 设置地图模式
router.post('/set-mode', (req, res) => {
  console.log('===== 设置地图模式请求 =====');
  console.log('请求数据:', req.body);
  
  const { mode } = req.body;
  
  if (mode !== 'online' && mode !== 'offline') {
    console.error('无效的地图模式:', mode);
    return res.status(400).json({ 
      success: false, 
      error: '无效的地图模式，必须是 online 或 offline'
    });
  }
  
  // 更新应用实例的全局模式设置
  if (req.app && req.app.locals) {
    req.app.locals.mapMode = mode;
    console.log('地图模式已设置为:', mode);
    res.json({ 
      success: true, 
      mode: mode 
    });
  } else {
    console.error('无法访问应用实例，模式设置失败');
    res.status(500).json({ 
      success: false, 
      error: '服务器内部错误，模式设置失败'
    });
  }
});

// 保存离线地图瓦片
router.post('/save-tile', async (req, res) => {
  console.log('===== 保存离线地图瓦片请求 =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求方法:', req.method);
  console.log('请求体参数:', { z: req.body.z, x: req.body.x, y: req.body.y, layer: req.body.layer, format: req.body.format, data: req.body.data ? '数据已提供' : '无数据' });
  
  try {
    const { z, x, y, layer, format, data } = req.body;
    
    if (!z || !x || !y || !layer || !data) {
      console.log('缺少必要参数，返回400错误');
      return res.status(400).json({ error: '缺少必要参数' });
    }
    
    // 创建保存路径
    const tileDir = path.join(offlineMapDir, layer, z.toString(), x.toString());
    await fs.ensureDir(tileDir);
    
    // 保存瓦片数据
    const tilePath = path.join(tileDir, `${y}.${format}`);
    await fs.writeFile(tilePath, Buffer.from(data, 'base64'));
    
    console.log(`瓦片保存成功: ${layer}/${z}/${x}/${y}.${format}`);
    res.json({ success: true, message: '瓦片保存成功' });
  } catch (error) {
    console.error('保存瓦片失败:', error);
    res.status(500).json({ error: '保存瓦片失败' });
  }
});

// 获取离线地图瓦片（已注释，避免与优化版本冲突）
// router.get('/offline-tile/:layer/:path/:z/:x/:y.:format', async (req, res) => {
//   console.log('===== 获取离线地图瓦片请求 =====');
//   console.log('请求URL:', req.originalUrl);
//   console.log('请求方法:', req.method);
//   console.log('请求参数:', req.params);
//   
//   try {
//     const { layer, path: mapPath, z, x, y, format } = req.params;
//     
//     // 构建正确的瓦片文件路径
//     const tilePath = path.join(offlineMapDir, mapPath, z, x, `${y}.${format}`);
//     
//     if (await fs.pathExists(tilePath)) {
//       console.log(`瓦片存在，返回文件: ${mapPath}/${z}/${x}/${y}.${format}`);
//       res.sendFile(tilePath);
//     } else {
//       console.log(`瓦片不存在: ${mapPath}/${z}/${x}/${y}.${format}`);
//       res.status(404).json({ error: '瓦片不存在' });
//     }
//   } catch (error) {
//     console.error('获取瓦片失败:', error);
//     res.status(500).json({ error: '获取瓦片失败' });
//   }
// });

// 保存离线地图（客户端请求的接口）
router.post('/save-offline', async (req, res) => {
  console.log('===== 保存离线地图请求 =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求方法:', req.method);
  console.log('请求体参数:', req.body);
  
  try {
    const { bounds, minZoom, maxZoom, mapType, name } = req.body;
    
    if (!bounds || !minZoom || !maxZoom || !mapType) {
      console.log('缺少必要参数，返回400错误');
      return res.status(400).json({ error: '缺少必要参数' });
    }
    
    // 解析边界框参数 - 支持 {sw:[lng,lat],ne:[lng,lat]} 格式
    let minLng, minLat, maxLng, maxLat;
    
    if (bounds.sw && bounds.ne) {
      // 新格式: {sw:[lng,lat],ne:[lng,lat]}
      minLng = bounds.sw[0];
      minLat = bounds.sw[1];
      maxLng = bounds.ne[0];
      maxLat = bounds.ne[1];
    } else {
      // 旧格式: {minLat, minLng, maxLat, maxLng}
      minLat = bounds.minLat;
      minLng = bounds.minLng;
      maxLat = bounds.maxLat;
      maxLng = bounds.maxLng;
    }
    
    // 验证边界框坐标
    if (typeof minLat !== 'number' || typeof minLng !== 'number' || 
        typeof maxLat !== 'number' || typeof maxLng !== 'number') {
      return res.status(400).json({ error: '边界框坐标格式错误' });
    }
    
    // 创建天地图服务实例
    const tiandituService = new TiandituService(process.env.TIANDITU_API_KEY);
    
    // 获取边界内的所有瓦片
    const tiles = getTilesInBoundingBox(
      minLat, minLng, 
      maxLat, maxLng, 
      minZoom, maxZoom
    );
    
    console.log(`需要下载的瓦片总数: ${tiles.length}`);
    
    // 创建地图保存记录
    const mapRecord = {
      id: Date.now().toString(),
      timestamp: new Date().toISOString(),
      bounds: bounds,
      minZoom: minZoom,
      maxZoom: maxZoom,
      mapType: mapType,
      tilesCount: tiles.length
    };
    
    // 确保地图记录目录存在
    const mapRecordsDir = path.join(offlineMapDir, 'records');
    await fs.ensureDir(mapRecordsDir);
    
    // 保存地图记录
    const recordPath = path.join(mapRecordsDir, `${mapRecord.id}.json`);
    await fs.writeJson(recordPath, mapRecord);
    
    // 模拟下载进度（实际应该在后台任务中处理）
    let tilesDownloaded = 0;
    
    // 下载所有计算出的瓦片
    const tilesToDownload = tiles;
    
    for (const tile of tilesToDownload) {
      try {
        // 根据新的目录结构保存瓦片文件
        // 基础图层瓦片 - 路径格式: /offline-maps/vector/[mapType]/z/x/y.png
        const baseData = await tiandituService.fetchTile(mapType, tile.z, tile.x, tile.y);
        const baseDir = path.join(offlineMapDir, 'vector', mapType, tile.z.toString(), tile.x.toString());
        await fs.ensureDir(baseDir);
        await fs.writeFile(path.join(baseDir, `${tile.y}.png`), baseData);
        console.log(`已保存基础图层瓦片: vector/${mapType}/${tile.z}/${tile.x}/${tile.y}.png`);
        
        // 标签图层瓦片 - 路径格式: /offline-maps/vector/[mapType]Label/z/x/y.png
        const labelType = `${mapType}Label`;
        const labelData = await tiandituService.fetchTile(labelType, tile.z, tile.x, tile.y);
        const labelDir = path.join(offlineMapDir, 'vector', labelType, tile.z.toString(), tile.x.toString());
        await fs.ensureDir(labelDir);
        await fs.writeFile(path.join(labelDir, `${tile.y}.png`), labelData);
        console.log(`已保存标签图层瓦片: vector/${labelType}/${tile.z}/${tile.x}/${tile.y}.png`);
        
        tilesDownloaded += 1;
        console.log(`已下载瓦片: ${tilesDownloaded}/${tilesToDownload.length}`);
        
      } catch (error) {
        console.error(`下载瓦片失败 ${mapType} ${tile.z}/${tile.x}/${tile.y}:`, error.message);
        // 继续下载其他瓦片
      }
    }
    
    console.log(`瓦片下载完成，实际下载: ${tilesDownloaded} 个`);
    
    res.json({
      success: true,
      message: '离线地图保存成功',
      tilesDownloaded: tilesDownloaded,
      totalTiles: tiles.length,
      mapId: mapRecord.id
    });
  } catch (error) {
    console.error('保存离线地图失败:', error);
    res.status(500).json({ error: '保存离线地图失败', details: error.message });
  }
});

// 获取已保存的离线地图列表
router.get('/saved-maps', async (req, res) => {
  console.log('===== 获取已保存的离线地图列表请求 =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求方法:', req.method);
  
  try {
    const mapRecordsDir = path.join(offlineMapDir, 'records');
    
    if (!await fs.pathExists(mapRecordsDir)) {
      console.log('地图记录目录不存在，返回空列表');
      return res.json([]);
    }
    
    const recordFiles = await fs.readdir(mapRecordsDir);
    console.log(`找到 ${recordFiles.length} 个记录文件`);
    const mapsList = [];
    
    for (const file of recordFiles) {
      if (file.endsWith('.json')) {
        const recordPath = path.join(mapRecordsDir, file);
        try {
          const mapRecord = await fs.readJson(recordPath);
          // 验证记录的有效性
          if (mapRecord && mapRecord.id && mapRecord.mapType && mapRecord.timestamp) {
            mapsList.push(mapRecord);
            console.log(`加载地图记录: ${mapRecord.id}, 类型: ${mapRecord.mapType}`);
          }
        } catch (parseError) {
          console.error(`解析地图记录文件失败: ${file}`, parseError);
        }
      }
    }
    
    // 按时间戳排序，最新的在前
    mapsList.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
    
    console.log(`成功加载 ${mapsList.length} 个有效的离线地图记录`);
    res.json(mapsList);
  } catch (error) {
    console.error('获取已保存地图列表失败:', error);
    res.status(500).json({ error: '获取地图列表失败', details: error.message });
  }
});

// 获取特定ID的已保存地图配置
router.get('/saved-map/:mapId', async (req, res) => {
  console.log('===== 获取特定ID的已保存地图请求 =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求方法:', req.method);
  console.log('地图ID:', req.params.mapId);
  
  try {
    const mapId = req.params.mapId;
    const mapRecordsDir = path.join(offlineMapDir, 'records');
    const recordPath = path.join(mapRecordsDir, `${mapId}.json`);
    
    // 检查文件是否存在
    if (!await fs.pathExists(recordPath)) {
      return res.status(404).json({ error: '地图不存在' });
    }
    
    // 读取地图配置
    const mapRecord = await fs.readJson(recordPath);
    
    // 确保tiandituService实例已创建
    const tiandituService = new TiandituService(process.env.TIANDITU_API_KEY);
    
    // 更新离线地图样式中的地图类型，同时传递showLabels参数
    const showLabels = req.query.showLabels === 'true';
    offlineMapStyle = tiandituService.getOfflineMapStyle(mapRecord.mapType, showLabels);
    isOfflineMapStyleUpdated = true;
    
    res.json(mapRecord);
  } catch (error) {
    console.error('获取已保存地图配置失败:', error);
    res.status(500).json({ error: '获取地图配置失败', details: error.message });
  }
});

// 删除已保存的离线地图
router.delete('/delete-map/:id', async (req, res) => {
  console.log('===== 删除已保存的离线地图请求 =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求方法:', req.method);
  console.log('地图ID:', req.params.id);
  
  try {
    const mapId = req.params.id;
    const mapRecordsDir = path.join(offlineMapDir, 'records');
    const recordPath = path.join(mapRecordsDir, `${mapId}.json`);
    
    if (!await fs.pathExists(recordPath)) {
      return res.status(404).json({ error: '地图不存在' });
    }
    
    // 读取地图记录
    const mapRecord = await fs.readJson(recordPath);
    
    // 删除地图记录文件
    await fs.unlink(recordPath);
    
    // 这里可以选择删除对应的瓦片文件
    // 为简化示例，我们只删除记录文件
    
    console.log(`地图 ${mapId} 删除成功`);
    res.json({ success: true, message: '地图删除成功' });
  } catch (error) {
    console.error('删除离线地图失败:', error);
    res.status(500).json({ error: '删除离线地图失败' });
  }
});

// 获取地图样式配置 - 统一路由，根据运行模式返回相应配置
router.get('/style', async (req, res) => {
    console.log('===== 地图样式请求 =====');
    console.log('请求URL:', req.originalUrl);
    console.log('请求方法:', req.method);
    console.log('请求参数:', req.query);
    
    try {
        // 获取当前地图模式
        let mode = 'online'; // 默认在线模式
        try {
            if (req.app && req.app.locals) {
                mode = req.app.locals.mapMode || 'online';
                console.log(`[样式路由] 从应用实例获取模式: ${mode}`);
            }
        } catch (error) {
            console.error(`[样式路由] 获取模式时出错:`, error);
        }
        
        const mapType = req.query.type || 'vector'; // 默认矢量图
        const showLabels = req.query.showLabels === 'true'; // 是否显示标注
        
        // 创建天地图服务实例
        const tiandituService = new TiandituService(process.env.TIANDITU_API_KEY);
        
        // 根据运行模式选择不同的样式生成方法
        let style;
        if (mode === 'offline') {
            console.log(`[样式路由] 离线模式 - 使用离线地图样式`);
            style = tiandituService.getOfflineMapStyle(mapType, showLabels);
        } else {
            console.log(`[样式路由] 在线模式 - 使用在线地图样式`);
            
            // 根据请求的地图类型动态生成正确的瓦片URL
            // 定义不同地图类型对应的路径和图层
            const mapTypeConfig = {
                vector: { path: 'vec_w', layer: 'vec', labelPath: 'cva_w', labelLayer: 'cva' },
                terrain: { path: 'ter_w', layer: 'ter', labelPath: 'cta_w', labelLayer: 'cta' },
                image: { path: 'img_w', layer: 'img', labelPath: 'cia_w', labelLayer: 'cia' }
            };
            
            // 获取对应的配置，如果不存在则默认为矢量图
            const config = mapTypeConfig[mapType] || mapTypeConfig.vector;
            
            // 修改瓦片URL指向本地代理服务器，不再直接访问天地图
            const localTileUrl = `/api/map/proxy-tile/${config.path}/${config.layer}/{z}/{x}/{y}.png`;
            
            style = {
                version: 8,
                sources: {
                    'raster-tiles': {
                        type: 'raster',
                        tiles: [localTileUrl],
                        tileSize: 256,
                        minzoom: 1,
                        maxzoom: 18
                    }
                },
                layers: [
                    {
                        id: 'raster-layer',
                        type: 'raster',
                        source: 'raster-tiles'
                    }
                ],
                // 正确配置glyphs和sprite
                sprite: '',
                glyphs: '/api/map/font/{fontstack}/{range}.pbf'
            };
            
            // 如果需要显示标注，添加标注图层
            if (showLabels) {
                const labelTileUrl = `/api/map/proxy-tile/${config.labelPath}/${config.labelLayer}/{z}/{x}/{y}.png`;
                
                // 添加标注图层源
                style.sources['label-tiles'] = {
                    type: 'raster',
                    tiles: [labelTileUrl],
                    tileSize: 256,
                    minzoom: 1,
                    maxzoom: 18
                };
                
                // 添加标注图层
                style.layers.push({
                    id: 'label-layer',
                    type: 'raster',
                    source: 'label-tiles'
                });
            }
        }
        
        console.log(`[样式路由] 返回${mode}模式的地图样式，类型: ${mapType}`);
        res.json(style);
    } catch (error) {
        console.error('[样式路由] 生成地图样式失败:', error);
        res.status(500).json({ error: '生成地图样式失败', details: error.message });
    }
});

// 全局请求队列和并发控制
const requestQueue = [];
let activeRequests = 0; // 当前活跃的请求数
// 从环境变量读取最大并发请求数，默认值为10
const DEFAULT_MAX_CONCURRENT = 10;
let maxConcurrentRequests = (() => {
    const envValue = parseInt(process.env.MAX_CONCURRENT_REQUESTS, 10);
    return (!isNaN(envValue) && envValue >= 1 && envValue <= 20) ? envValue : DEFAULT_MAX_CONCURRENT;
})();

// 记录初始化的并发配置
console.log(`[并发控制] 初始化配置完成 - 最大并发请求数: ${maxConcurrentRequests}`);
if (process.env.MAX_CONCURRENT_REQUESTS) {
    const envValue = parseInt(process.env.MAX_CONCURRENT_REQUESTS, 10);
    if (isNaN(envValue) || envValue < 1 || envValue > 20) {
        console.log(`[并发控制] 注意: 环境变量中MAX_CONCURRENT_REQUESTS的值(${process.env.MAX_CONCURRENT_REQUESTS})无效，已使用默认值${DEFAULT_MAX_CONCURRENT}`);
    }
}

/**
 * 设置最大并发请求数
 * @param {number} count - 最大并发请求数
 */
exports.setMaxConcurrentRequests = function(count) {
    if (typeof count === 'number' && count > 0 && count <= 20) { // 设置合理的上限
        maxConcurrentRequests = count;
        console.log(`[并发控制] 最大并发请求数已设置为: ${count}`);
        return true;
    }
    console.error(`[并发控制] 无效的并发数设置: ${count}，必须为1-20之间的数字`);
    return false;
};

/**
 * 获取当前并发控制状态
 * @returns {Object} 当前状态信息
 */
exports.getConcurrentStatus = function() {
    return {
        activeRequests: activeRequests,
        maxConcurrentRequests: maxConcurrentRequests,
        queueLength: requestQueue.length
    };
};

// 处理请求队列 - 支持可配置的并发执行
async function processRequestQueue() {
    // 当队列不为空且活跃请求数小于最大并发数时，处理新请求
    while (requestQueue.length > 0 && activeRequests < maxConcurrentRequests) {
        // 增加活跃请求计数
        activeRequests++;
        console.log(`[并发控制] 开始处理新请求，当前活跃请求: ${activeRequests}/${maxConcurrentRequests}，队列剩余: ${requestQueue.length}`);
        
        // 从队列中取出一个请求
        const { req, res, handler } = requestQueue.shift();
        
        // 异步处理请求，不阻塞循环
        (async () => {
            try {
                // 执行请求处理函数
                await handler(req, res);
            } catch (error) {
                console.error(`[队列处理] 请求处理失败:`, error);
                // 确保响应返回，避免客户端一直等待
                if (!res.headersSent) {
                    res.contentType('image/png');
                    res.send(TRANSPARENT_PNG_BUFFER);
                }
            } finally {
                // 减少活跃请求计数
                activeRequests--;
                console.log(`[并发控制] 请求处理完成，当前活跃请求: ${activeRequests}/${maxConcurrentRequests}`);
                
                // 请求完成后，检查队列中是否还有待处理的请求
                if (requestQueue.length > 0) {
                    // 短延迟后再处理下一批，避免过于密集
                    setTimeout(processRequestQueue, 10);
                }
            }
        })();
        
        // 为了避免瞬间创建过多请求，添加微小延迟
        await new Promise(resolve => setTimeout(resolve, 10));
    }
}

// 带重试机制的HTTP请求 - 增强版，实现更智能的退避策略
async function fetchWithRetry(url, options, maxRetries = 3, baseDelay = 30) {
    // 第一次尝试前增加随机延迟，避免请求风暴
    await new Promise(resolve => setTimeout(resolve, 50 + Math.random() * 10));
    
    // 创建包含必要请求头的options对象
    const requestOptions = {
        ...options,
        headers: {
            ...options.headers,
            // 添加浏览器风格的User-Agent，避免被识别为爬虫
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
            'Accept': 'image/png,image/*;q=0.8,*/*;q=0.5',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Referer': 'https://map.tianditu.gov.cn/'
        }
    };
    
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            console.log(`[重试机制] 第${attempt}/${maxRetries}次尝试请求: ${url}`);
            const response = await axios.get(url, requestOptions);
            console.log(`[重试机制] 请求成功，状态码: ${response.status}`);
            return response;
        } catch (error) {
            // 如果是429错误且还有重试次数，延迟后重试
            if (error.response && error.response.status === 429 && attempt < maxRetries) {
                // 指数退避策略，每次重试时间增加，同时加入随机因素
                const backoffTime = baseDelay * Math.pow(2, attempt - 1) + Math.random() * 2000;
                console.log(`[重试机制] 第${attempt}次请求失败(429)，${Math.round(backoffTime)}ms后重试...`);
                await new Promise(resolve => setTimeout(resolve, backoffTime));
            } 
            // 处理403 Forbidden错误，特殊处理，尝试增加更多头信息
            else if (error.response && error.response.status === 403 && attempt < maxRetries) {
                console.log(`[重试机制] 第${attempt}次请求失败(403)，添加更多头信息后重试...`);
                // 增加额外的头信息，模拟浏览器环境
                requestOptions.headers['Origin'] = 'https://map.tianditu.gov.cn';
                requestOptions.headers['Cache-Control'] = 'no-cache';
                // 短暂延迟后重试
                await new Promise(resolve => setTimeout(resolve, 2000));
            }
            else {
                // 输出详细错误信息，方便调试
                console.error(`[重试机制] 请求失败${attempt === maxRetries ? '，已达最大重试次数' : ''}:`, 
                    error.response ? `${error.response.status} ${error.response.statusText}` : error.message);
                throw error; // 其他错误或重试次数用尽，抛出异常
            }
        }
    }
}

// 代理天地图瓦片请求，实现瓦片缓存 - 支持离线/在线模式
router.get('/proxy-tile/:path/:layer/:z/:x/:y.:format', async (req, res) => {
    console.log('===== 瓦片代理请求 =====');
    console.log('请求URL:', req.originalUrl);
    console.log('请求参数:', req.params);
    console.log('请求查询参数:', req.query);
    
    try {
        const { path: mapPath, layer, z, x, y, format } = req.params;
        
        // 确保能正确访问应用实例的全局设置
        let mode = 'offline'; // 默认值
        try {
            if (req.app && req.app.locals) {
                mode = req.app.locals.mapMode || 'offline';
                console.log(`[瓦片代理] 从应用实例获取模式: ${mode}`);
            } else {
                console.log(`[瓦片代理] 无法访问应用实例，使用默认离线模式`);
            }
        } catch (error) {
            console.error(`[瓦片代理] 获取模式时出错:`, error);
        }
        
        const safeZ = String(z);
        const safeX = String(x);
        const safeY = String(y);
        const fileName = `${safeY}.${format}`;
        
        // 根据mapPath和layer确定内部地图类型
        let internalType;
        if (mapPath === 'vec_w' && layer === 'vec') internalType = 'vector';
        else if (mapPath === 'img_w' && layer === 'img') internalType = 'image';
        else if (mapPath === 'ter_w' && layer === 'ter') internalType = 'terrain';
        else if (mapPath === 'cva_w' && layer === 'cva') internalType = 'vectorLabel';
        else if (mapPath === 'cia_w' && layer === 'cia') internalType = 'imageLabel';
        else if (mapPath === 'cta_w' && layer === 'cta') internalType = 'terrainLabel';
        else {
            // 默认使用vector类型
            console.log(`[瓦片代理] 未知的地图类型组合: ${mapPath}/${layer}，使用默认类型`);
            internalType = 'vector';
        }
        
        console.log(`[瓦片代理] 尝试查找瓦片: ${mapPath}/${layer}/${safeZ}/${safeX}/${fileName}`);
        console.log(`[瓦片代理] 运行模式: ${mode}`);
        console.log(`[瓦片代理] MBTiles模式: ${enableMbtiles ? '启用' : '禁用'}`);
        
        // 1. 首先尝试从MBTiles获取瓦片（如果启用了MBTiles模式）
        if (enableMbtiles && mbtilesService) {
            try {
                console.log(`[瓦片代理] 尝试从MBTiles获取瓦片: ${internalType}/${safeZ}/${safeX}/${safeY}.${format}`);
                const tileBuffer = await mbtilesService.getTile(internalType, parseInt(safeZ), parseInt(safeX), parseInt(safeY));
                
                if (tileBuffer) {
                    console.log(`[瓦片代理] 从MBTiles成功获取瓦片，大小: ${tileBuffer.length} 字节`);
                    res.contentType(format === 'png' ? 'image/png' : 'application/octet-stream');
                    // 设置缓存控制头，让浏览器缓存瓦片
                    res.set('Cache-Control', 'public, max-age=31536000, immutable');
                    return res.send(tileBuffer);
                }
                console.log(`[瓦片代理] MBTiles中未找到瓦片`);
            } catch (error) {
                console.error(`[瓦片代理] 从MBTiles获取瓦片时出错:`, error.message);
            }
        }
        
        // 2. 如果MBTiles未启用或未找到瓦片，尝试从文件系统获取
        const tilePath = path.join(offlineMapDir, internalType, safeZ, safeX, fileName);
        console.log(`[瓦片代理] 尝试从文件系统查找瓦片: ${tilePath}`);
        
        // 检查瓦片文件是否存在
        let fileExists = false;
        if (await fs.pathExists(tilePath)) {
            const stat = await fs.stat(tilePath);
            fileExists = stat.isFile();
            if (fileExists) {
                console.log(`[瓦片代理] 找到瓦片文件: ${tilePath}`);
            }
        }
        
        // 如果找到瓦片文件，直接返回
        if (fileExists) {
            const stat = await fs.stat(tilePath);
            console.log(`[瓦片代理] 文件存在且有效，大小: ${stat.size} 字节`);
            res.contentType(format === 'png' ? 'image/png' : 'application/octet-stream');
            // 设置缓存控制头，让浏览器缓存瓦片
            res.set('Cache-Control', 'public, max-age=31536000, immutable');
            return res.sendFile(tilePath);
        }
        
        // 缓存未命中
        console.log(`[瓦片代理] 在所有可能的路径中都未找到瓦片文件`);
        
        // 根据模式决定后续行为
        if (mode === 'online') {
            console.log(`[瓦片代理] 在线模式：尝试从天地图服务器获取瓦片并缓存`);
            
            try {
                // 创建天地图服务实例
                const tiandituService = new TiandituService(process.env.TIANDITU_API_KEY);
                
                // 根据mapPath和layer确定内部地图类型
                let internalType;
                if (mapPath === 'vec_w' && layer === 'vec') internalType = 'vector';
                else if (mapPath === 'img_w' && layer === 'img') internalType = 'image';
                else if (mapPath === 'ter_w' && layer === 'ter') internalType = 'terrain';
                else if (mapPath === 'cva_w' && layer === 'cva') internalType = 'vectorLabel';
                else if (mapPath === 'cia_w' && layer === 'cia') internalType = 'imageLabel';
                else if (mapPath === 'cta_w' && layer === 'cta') internalType = 'terrainLabel';
                else {
                    // 默认使用vector类型
                    console.log(`[瓦片代理] 未知的地图类型组合: ${mapPath}/${layer}，使用默认类型`);
                    internalType = 'vector';
                }
                
                // 构建天地图URL并获取瓦片数据
                console.log(`[瓦片代理] 使用内部类型 ${internalType} 构建URL`);
                const tileData = await fetchWithRetry(
                    tiandituService.getTileUrl(internalType, safeZ, safeX, safeY),
                    { responseType: 'arraybuffer' }
                );
                
                // 创建确定的缓存路径（使用标准路径格式）
                const cachePath = path.join(offlineMapDir, internalType, safeZ, safeX, fileName);
                const cacheDir = path.dirname(cachePath);
                await fs.ensureDir(cacheDir);
                
                // 保存瓦片数据到缓存（使用更可靠的写入方式）
                await fs.writeFile(cachePath, Buffer.from(tileData.data));
                console.log(`[瓦片代理] 瓦片已成功缓存到: ${cachePath}`);
                
                // 返回瓦片数据并设置缓存头
                res.contentType(format === 'png' ? 'image/png' : 'application/octet-stream');
                res.set('Cache-Control', 'public, max-age=31536000, immutable');
                res.send(Buffer.from(tileData.data));
            } catch (error) {
                console.error('[瓦片代理] 在线获取瓦片失败:', error.message);
                
                // 即使获取失败，也尝试从offline-tile路由查找可能存在的瓦片
                console.log('[瓦片代理] 尝试从offline-tile路由查找备用瓦片');
                try {
                    // 确定对应的mapType
                    let mapType = 'vector';
                    if (baseDir === 'image') mapType = 'image';
                    else if (baseDir === 'terrain') mapType = 'terrain';
                    
                    const offlineTilePath = path.join(offlineMapDir, mapType, layer, safeZ, safeX, fileName);
                    if (await fs.pathExists(offlineTilePath)) {
                        const stat = await fs.stat(offlineTilePath);
                        if (stat.isFile()) {
                            console.log(`[瓦片代理] 找到备用瓦片: ${offlineTilePath}`);
                            res.contentType('image/png');
                            res.set('Cache-Control', 'public, max-age=31536000, immutable');
                            return res.sendFile(offlineTilePath);
                        }
                    }
                } catch (offlineError) {
                    console.error('[瓦片代理] 查找备用瓦片失败:', offlineError.message);
                }
                
                // 如果所有尝试都失败，返回透明瓦片
                res.contentType('image/png');
                // 设置不缓存头，避免浏览器缓存不存在的瓦片
                res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
                res.set('Pragma', 'no-cache');
                res.set('Expires', '0');
                res.send(TRANSPARENT_PNG_BUFFER);
            }
        } else {
            console.log(`[瓦片代理] 离线模式：只检查本地缓存，不尝试远程获取`);
            
            // 由于前面已经检查了多种可能的路径格式，如果还没找到，则确认瓦片不存在
            console.log(`[瓦片代理] 离线模式下所有可能路径都未找到瓦片`);
            
            // 如果所有路径都没有找到瓦片，返回透明瓦片
            res.contentType('image/png');
            // 设置不缓存头，避免浏览器缓存不存在的瓦片
            res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
            res.set('Pragma', 'no-cache');
            res.set('Expires', '0');
            res.send(TRANSPARENT_PNG_BUFFER);
        }
    } catch (error) {
        console.error(`[瓦片代理] 处理请求时发生错误:`, error);
        // 错误情况下也返回透明瓦片
        res.contentType('image/png');
        // 设置不缓存头，避免浏览器缓存错误瓦片
        res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
        res.set('Pragma', 'no-cache');
        res.set('Expires', '0');
        res.send(TRANSPARENT_PNG_BUFFER);
    }
});

// 获取离线地图样式
router.get('/offline-style', async (req, res) => {
  console.log('===== 获取离线地图样式请求 =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求方法:', req.method);
  
  try {
    // 从请求中获取地图类型，如果没有提供则使用默认的vector类型
    const requestedMapType = req.query.type || 'vector';
    const showLabels = req.query.showLabels === 'true'; // 是否显示标注
    
    // 创建天地图服务实例
    const tiandituService = new TiandituService(process.env.TIANDITU_API_KEY);
    
    // 使用请求的地图类型获取对应的样式
    const style = tiandituService.getOfflineMapStyle(requestedMapType, showLabels);
    
    // 更新全局地图样式状态
    offlineMapStyle = style;
    isOfflineMapStyleUpdated = true;
    
    console.log(`使用地图类型: ${requestedMapType} 生成样式，显示标注: ${showLabels}`);
    res.json(style);
  } catch (error) {
    console.error('获取离线地图样式失败:', error);
    res.status(500).json({ error: '获取离线地图样式失败' });
  }
});

// 获取离线地图瓦片 - 优化版本
router.get('/offline-tile/:mapType/:layer/:z/:x/:y.:format', async (req, res) => {
  console.log('===== 获取离线地图瓦片请求 =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求参数:', JSON.stringify(req.params, null, 2));
  
  try {
    const { mapType, layer, z, x, y, format } = req.params;
    const pathModule = require('path'); // 在函数内重新引入path模块避免冲突
    
    // 安全处理参数，防止路径遍历攻击
    const safeMapType = pathModule.basename(mapType);
    const safeLayer = pathModule.basename(layer);
    const safeZ = pathModule.basename(z);
    const safeX = pathModule.basename(x);
    const safeY = pathModule.basename(y);
    const safeFormat = pathModule.basename(format);
    const fileName = `${safeY}.${safeFormat}`;
    
    // 构建多个可能的瓦片路径
    const possiblePaths = [
      // 标准路径: offline-maps/mapType/layer/z/x/y.format
      pathModule.join(offlineMapDir, safeMapType, safeLayer, safeZ, safeX, fileName),
      // 备选路径: offline-maps/layer/mapPath/z/x/y.format (保持兼容性)
      pathModule.join(offlineMapDir, safeLayer, safeMapType, safeZ, safeX, fileName),
      // 标准路径: offline-maps/vector/mapPath/z/x/y.format (保持兼容性)
      pathModule.join(offlineMapDir, 'vector', safeMapType, safeZ, safeX, fileName),
      // 简化路径: offline-maps/mapPath/z/x/y.format (保持兼容性)
      pathModule.join(offlineMapDir, safeMapType, safeZ, safeX, fileName),
      // 直接路径: offline-maps/z/x/y.format
      pathModule.join(offlineMapDir, safeZ, safeX, fileName)
    ];
    
    // 添加详细的路径调试信息
    console.log(`[瓦片查找] 尝试查找瓦片: ${safeMapType}/${safeLayer}/${safeZ}/${safeX}/${fileName}`);
    console.log(`[瓦片查找] 搜索路径列表:`, possiblePaths);
    
    // 检查所有可能的路径，返回第一个存在的瓦片
    for (const tilePath of possiblePaths) {
      const exists = await fs.pathExists(tilePath);
      console.log(`[瓦片查找] 检查路径: ${tilePath}, 存在: ${exists}`);
      
      if (exists) {
        // 验证是文件而不是目录
        const stat = await fs.stat(tilePath);
        console.log(`[瓦片查找] 是文件: ${stat.isFile()}, 大小: ${stat.size} 字节`);
        
        if (stat.isFile()) {
          // 根据格式设置合适的content-type
          res.contentType(safeFormat === 'png' ? 'image/png' : 'application/octet-stream');
          console.log(`[瓦片查找] 成功找到瓦片: ${tilePath}`);
          return res.sendFile(tilePath);
        }
      }
    }
    
    // 如果所有路径都不存在，返回预定义的透明PNG图片
    console.log(`[瓦片查找] 瓦片不存在: ${safeMapType}/${safeLayer}/${safeZ}/${safeX}/${fileName}`);
    
    // 设置响应头并返回预定义的透明PNG图片
    res.contentType('image/png');
    // 设置不缓存头，避免浏览器缓存不存在的瓦片
    res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
    res.set('Pragma', 'no-cache');
    res.set('Expires', '0');
    return res.send(TRANSPARENT_PNG_BUFFER);
  } catch (error) {
    console.error('[瓦片查找] 获取离线瓦片时出错:', error);
    res.status(500).json({ error: '获取瓦片失败' });
  }
});


// 字体文件代理路由 - 支持本地缓存
router.get('/font/:fontstack/:range.pbf', async (req, res) => {
  console.log('===== 字体文件请求 =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求参数:', req.params);
  
  try {
    const { fontstack, range } = req.params;
    
    // 构建本地缓存路径
    const fontCacheDir = path.join(offlineMapDir, 'font-cache', fontstack);
    const fontFilePath = path.join(fontCacheDir, `${range}.pbf`);
    
    // 检查字体文件是否已经缓存
    if (await fs.pathExists(fontFilePath)) {
      console.log(`[字体代理] 字体文件已缓存，从本地返回: ${fontFilePath}`);
      res.set('Content-Type', 'application/x-protobuf');
      return res.sendFile(fontFilePath);
    }
    
    // 使用本地字体文件路径，添加字体映射逻辑
    console.log(`[字体代理] 使用本地字体文件`);
    // 字体映射：将sans-serif映射到Noto Sans Regular
    const fontMapping = {
      'sans-serif': 'Noto Sans Regular'
    };
    // 获取实际的字体目录名
    const actualFontStack = fontMapping[fontstack] || fontstack;
    console.log(`[字体代理] 映射字体: ${fontstack} -> ${actualFontStack}`);
    
    const localFontDir = path.join('data', 'demotiles', 'font', actualFontStack);
    const localFontFilePath = path.join(localFontDir, `${range}.pbf`);
    
    // 检查本地字体文件是否存在
    if (await fs.pathExists(localFontFilePath)) {
      console.log(`[字体代理] 本地字体文件存在，从本地返回: ${localFontFilePath}`);
      res.set('Content-Type', 'application/x-protobuf');
      return res.sendFile(path.resolve(localFontFilePath));
    }
    
    // 如果本地文件不存在，可以选择返回错误或继续远程获取
    console.log(`[字体代理] 本地字体文件不存在: ${localFontFilePath}`);
    // 这里暂时注释掉远程获取，只使用本地字体
    // const originalFontUrl = `https://demotiles.maplibre.org/font/${fontstack}/${range}.pbf`;
    
    // 本地字体文件不存在时的处理
    console.error('本地字体文件不存在:', localFontFilePath);
    
    // 离线模式下，如果字体文件不存在，返回空响应而不是错误
    if (req.app && req.app.locals && req.app.locals.mapMode === 'offline') {
      console.log('[字体代理] 离线模式下字体文件不存在，返回空响应');
      res.set('Content-Type', 'application/x-protobuf');
      res.status(200).send(Buffer.alloc(0)); // 返回空缓冲区
    } else {
      res.status(404).send('字体文件不存在');
    }
  } catch (error) {
    console.error('处理字体文件请求时出错:', error);
    res.status(500).json({ error: '处理字体文件请求时出错' });
  }
});

// 暂时移除Sprite相关路由，因为地图样式配置中不使用sprite
router.get('/cache/status', async (req, res) => {
  console.log('===== 缓存状态请求 =====');
  
  try {
    const fs = require('fs-extra');
    const path = require('path');
    
    // 统计缓存信息
    const getDirectorySize = async (dirPath) => {
      if (!(await fs.pathExists(dirPath))) return 0;
      
      let totalSize = 0;
      const files = await fs.readdir(dirPath);
      
      for (const file of files) {
        const filePath = path.join(dirPath, file);
        const stats = await fs.stat(filePath);
        
        if (stats.isDirectory()) {
          totalSize += await getDirectorySize(filePath);
        } else {
          totalSize += stats.size;
        }
      }
      
      return totalSize;
    };
    
    // 统计瓦片数量
    const countFiles = async (dirPath, extension = '.png') => {
      if (!(await fs.pathExists(dirPath))) return 0;
      
      let count = 0;
      const files = await fs.readdir(dirPath);
      
      for (const file of files) {
        const filePath = path.join(dirPath, file);
        const stats = await fs.stat(filePath);
        
        if (stats.isDirectory()) {
          count += await countFiles(filePath, extension);
        } else if (file.endsWith(extension)) {
          count++;
        }
      }
      
      return count;
    };
    
    // 执行统计
    const tileCount = await countFiles(offlineMapDir, '.png');
    const fontCount = await countFiles(path.join(offlineMapDir, 'font-cache'), '.pbf');
    const totalSize = await getDirectorySize(offlineMapDir);
    
    // 构建统计信息
    const stats = {
      cacheDir: offlineMapDir,
      tileCount,
      fontCount,
      totalSize,
      totalSizeFormatted: `${(totalSize / 1024 / 1024).toFixed(2)} MB`,
      lastUpdated: new Date().toISOString()
    };
    
    res.json({
      success: true,
      message: '缓存状态获取成功',
      data: stats
    });
  } catch (error) {
    console.error('获取缓存状态失败:', error);
    res.status(500).json({
      success: false,
      message: '获取缓存状态失败',
      error: error.message
    });
  }
});

// 缓存清理路由：清理指定类型或所有缓存
router.post('/cache/clear', async (req, res) => {
  console.log('===== 缓存清理请求 =====');
  console.log('请求体:', req.body);
  
  try {
    const fs = require('fs-extra');
    const path = require('path');
    
    const { type = 'all' } = req.body;
    
    let pathsToClear = [];
    
    switch (type) {
      case 'tiles':
        // 只清理瓦片缓存，保留字体等其他缓存
        pathsToClear = [
          path.join(offlineMapDir, 'vector'),
          path.join(offlineMapDir, 'image'),
          path.join(offlineMapDir, 'terrain'),
          path.join(offlineMapDir, 'proxy-cache')
        ];
        break;
      case 'fonts':
        // 只清理字体缓存
        pathsToClear = [path.join(offlineMapDir, 'font-cache')];
        break;
      case 'all':
      default:
        // 清理所有缓存，但保留目录结构
        pathsToClear = [offlineMapDir];
    }
    
    // 执行清理
    for (const clearPath of pathsToClear) {
      if (await fs.pathExists(clearPath)) {
        console.log(`清理缓存路径: ${clearPath}`);
        await fs.emptyDir(clearPath);
      }
    }
    
    res.json({
      success: true,
      message: `成功清理${type === 'all' ? '所有' : type === 'tiles' ? '瓦片' : '字体'}缓存`
    });
  } catch (error) {
    console.error('清理缓存失败:', error);
    res.status(500).json({
      success: false,
      message: '清理缓存失败',
      error: error.message
    });
  }
});

// 瓦片诊断路由：检查特定瓦片是否存在
router.get('/debug/tile-check', async (req, res) => {
  console.log('===== 瓦片诊断请求 =====');
  console.log('请求参数:', req.query);
  
  try {
    const { layer = 'vector', path: mapPath = 'vector', z = '11', x = '1686', y = '776', format = 'png' } = req.query;
    const pathModule = require('path'); // 重新引入path模块避免冲突
    
    // 确保参数都是字符串
    const zStr = String(z);
    const xStr = String(x);
    const yStr = String(y);
    const fileName = `${yStr}.${format}`;
    
    // 构建多个可能的路径
    const possiblePaths = [
      pathModule.join(offlineMapDir, 'vector', mapPath, zStr, xStr, fileName),
      pathModule.join(offlineMapDir, layer, mapPath, zStr, xStr, fileName),
      pathModule.join(offlineMapDir, mapPath, zStr, xStr, fileName)
    ];
    
    // 检查每个路径
    const results = [];
    for (const testPath of possiblePaths) {
      const exists = await fs.pathExists(testPath);
      let isFile = false;
      let size = 0;
      
      if (exists) {
        const stats = await fs.stat(testPath);
        isFile = stats.isFile();
        size = stats.size;
      }
      
      results.push({
        path: testPath,
        exists,
        isFile,
        size
      });
    }
    
    // 检查各级目录是否存在
    const vectorDir = pathModule.join(offlineMapDir, 'vector');
    const mapPathDir = pathModule.join(vectorDir, mapPath);
    const zDir = pathModule.join(mapPathDir, zStr);
    const xDir = pathModule.join(zDir, xStr);
    
    const dirChecks = {
      offlineMapDir: { exists: await fs.pathExists(offlineMapDir) },
      vectorDir: { exists: await fs.pathExists(vectorDir) },
      mapPathDir: { exists: await fs.pathExists(mapPathDir) },
      zDir: { exists: await fs.pathExists(zDir) },
      xDir: { exists: await fs.pathExists(xDir) }
    };
    
    // 如果X目录存在，列出其中的文件
    if (dirChecks.xDir.exists) {
      const files = await fs.readdir(xDir);
      dirChecks.xDir.files = files.slice(0, 20); // 限制返回的文件数量
      dirChecks.xDir.fileCount = files.length;
    }
    
    res.json({
      requested: { layer, mapPath, z, x, y, format },
      tileChecks: results,
      directoryChecks: dirChecks,
      offlineMapDirPath: String(offlineMapDir) // 只返回字符串形式的路径
    });
  } catch (error) {
    console.error('瓦片诊断失败:', error);
    res.status(500).json({ error: '瓦片诊断失败', details: error.message });
  }
});

// 离线地图目录结构检查路由
router.get('/debug/offline-dirs', async (req, res) => {
  try {
    const directoryInfo = {};
    const pathModule = require('path'); // 直接在函数内重新引入path模块以避免冲突
    
    // 检查根目录
    const rootExists = await fs.pathExists(offlineMapDir);
    directoryInfo.root = {
      path: String(offlineMapDir), // 转换为字符串避免循环引用
      exists: rootExists,
      isDirectory: rootExists ? (await fs.stat(offlineMapDir)).isDirectory() : false
    };
    
    // 如果根目录存在，检查vector目录
    if (rootExists) {
      const vectorDir = pathModule.join(offlineMapDir, 'vector');
      const vectorExists = await fs.pathExists(vectorDir);
      directoryInfo.vector = {
        path: String(vectorDir), // 转换为字符串避免循环引用
        exists: vectorExists,
        isDirectory: vectorExists ? (await fs.stat(vectorDir)).isDirectory() : false
      };
      
      // 如果vector目录存在，列出其中的内容
      if (vectorExists && directoryInfo.vector.isDirectory) {
        directoryInfo.vector.contents = await fs.readdir(vectorDir);
        
        // 检查vector目录下的子目录结构
        directoryInfo.vector.subdirs = {};
        for (const item of directoryInfo.vector.contents) {
          const itemPath = pathModule.join(vectorDir, item);
          const itemStat = await fs.stat(itemPath);
          if (itemStat.isDirectory()) {
            directoryInfo.vector.subdirs[item] = {
              path: String(itemPath), // 转换为字符串避免循环引用
              contents: await fs.readdir(itemPath).catch(() => [])
            };
          }
        }
      }
    }
    
    res.json(directoryInfo);
  } catch (error) {
    res.status(500).json({ error: '目录检查失败', details: error.message });
  }
});

// 获取已保存的离线地图信息（兼容旧接口）
router.get('/offline-maps', async (req, res) => {
  console.log('===== 获取已保存的离线地图信息请求 =====');
  console.log('请求URL:', req.originalUrl);
  console.log('请求方法:', req.method);
  console.log('请求参数:', req.query);
  
  try {
    // 详细验证离线地图根目录
    console.log(`[目录检查] 离线地图根目录路径: ${offlineMapDir}`);
    const rootExists = await fs.pathExists(offlineMapDir);
    console.log(`[目录检查] 离线地图根目录存在: ${rootExists}`);
    
    if (!rootExists) {
      console.error(`[目录错误] 离线地图根目录不存在: ${offlineMapDir}`);
      return res.status(404).json({ error: '离线地图目录不存在' });
    }
    
    // 列出根目录内容
    const rootContents = await fs.readdir(offlineMapDir);
    console.log(`[目录检查] 离线地图根目录内容: ${JSON.stringify(rootContents)}`);
    
    // 特别检查vector目录
    const vectorDir = path.join(offlineMapDir, 'vector');
    const vectorExists = await fs.pathExists(vectorDir);
    console.log(`[目录检查] vector目录存在: ${vectorExists}`);
    
    let mapsInfo = [];
    
    if (vectorExists) {
      const vectorContents = await fs.readdir(vectorDir);
      console.log(`[目录检查] vector目录内容: ${JSON.stringify(vectorContents)}`);
      
      // 遍历vector目录下的所有子目录（应该是地图类型，如vector、vectorLabel）
      for (const mapType of vectorContents) {
        const mapTypePath = path.join(vectorDir, mapType);
        if ((await fs.stat(mapTypePath)).isDirectory()) {
          console.log(`[目录检查] 发现地图类型目录: ${mapType}`);
          
          // 获取该地图类型下的所有缩放级别
          const zoomLevels = await fs.readdir(mapTypePath);
          const validZoomLevels = [];
          
          // 详细检查每个缩放级别
          for (const z of zoomLevels) {
            const zPath = path.join(mapTypePath, z);
            if ((await fs.stat(zPath)).isDirectory()) {
              // 获取该缩放级别下的X坐标目录数量
              const xDirs = await fs.readdir(zPath);
              console.log(`[目录检查] 缩放级别 ${z} 包含 ${xDirs.length} 个X坐标目录`);
              validZoomLevels.push(parseInt(z));
              
              // 对于调试，检查其中一个X目录的内容
              if (xDirs.length > 0) {
                const sampleXDir = xDirs[0];
                const sampleXPath = path.join(zPath, sampleXDir);
                const yFiles = await fs.readdir(sampleXPath);
                console.log(`[目录检查] 示例X目录 ${sampleXDir} 包含 ${yFiles.length} 个Y坐标文件`);
                if (yFiles.length > 0) {
                  console.log(`[目录检查] Y文件示例: ${yFiles.slice(0, 5).join(', ')}`);
                }
              }
            }
          }
          
          mapsInfo.push({
            layer: 'vector', // 因为我们现在在vector目录下
            path: mapType,    // 这是地图类型如vector、vectorLabel
            zoomLevels: validZoomLevels.sort((a, b) => a - b)
          });
        }
      }
    }
    
    console.log('[目录检查] 最终收集的地图信息:', JSON.stringify(mapsInfo));
    console.log('离线地图信息获取成功');
    res.json({ maps: mapsInfo });
  } catch (error) {
    console.error('获取离线地图信息失败:', error);
    res.status(500).json({ error: '获取离线地图信息失败' });
  }
});

module.exports = router;